import pygame
from constants import *
import random

class Renderer:
    def __init__(self, screen):
        self.screen = screen
        # 初始化字体
        pygame.font.init()
        try:
            self.font = pygame.font.SysFont(['SimHei', 'Microsoft YaHei', 'Arial'], 36)
            self.small_font = pygame.font.SysFont(['SimHei', 'Microsoft YaHei', 'Arial'], 24)
            self.title_font = pygame.font.SysFont(['SimHei', 'Microsoft YaHei', 'Arial'], 48, bold=True)
            self.large_font = pygame.font.SysFont(['SimHei', 'Microsoft YaHei', 'Arial'], 48, bold=True)
        except:
            self.font = pygame.font.SysFont('Arial', 36)
            self.small_font = pygame.font.SysFont('Arial', 24)
            self.title_font = pygame.font.SysFont('Arial', 48, bold=True)
            self.large_font = pygame.font.SysFont('Arial', 48, bold=True)
        
        # 计算游戏区域位置
        self.game_area_x = (SCREEN_WIDTH - GRID_WIDTH * GRID_SIZE) // 2 - 100
        self.next_area_x = self.game_area_x + GRID_WIDTH * GRID_SIZE + 50
        
        # 创建渐变背景
        self.create_background()
        
        # 动画参数
        self.fade_alpha = 0
        self.fade_direction = 1  # 1 增加，-1 减少
        self.score_flash = 0
        self.line_clear_animation = None
        # 粒子效果
        self.particles = []
    
    def create_background(self):
        """创建渐变背景"""
        self.background = pygame.Surface((SCREEN_WIDTH, SCREEN_HEIGHT))
        # 创建垂直渐变
        for y in range(SCREEN_HEIGHT):
            # 深蓝色到黑色的渐变
            r = int(20 * (1 - y / SCREEN_HEIGHT))
            g = int(20 * (1 - y / SCREEN_HEIGHT))
            b = int(80 * (1 - y / SCREEN_HEIGHT))
            pygame.draw.line(self.background, (r, g, b), (0, y), (SCREEN_WIDTH, y))
    
    def draw_title(self):
        """绘制游戏标题（简化版本确保显示）"""
        try:
            title_text = self.title_font.render("俄罗斯方块", True, (255, 255, 255))
            title_rect = title_text.get_rect(center=(SCREEN_WIDTH // 2, 50))
            self.screen.blit(title_text, title_rect)
        except Exception as e:
            # 如果字体渲染失败，使用简单的矩形代替
            pygame.draw.rect(self.screen, (255, 0, 0), (SCREEN_WIDTH // 2 - 100, 30, 200, 40))
    
    def draw_board(self, board, clearing_lines=None):
        """绘制游戏板，带网格线和方块阴影效果，支持动画效果"""
        # 调整游戏区域Y坐标，确保底部不被遮挡
        game_area_y = 30  # 上移20像素
        
        # 绘制游戏区域背景
        pygame.draw.rect(self.screen, (20, 20, 40), 
                        (self.game_area_x, game_area_y, GRID_WIDTH * GRID_SIZE, GRID_HEIGHT * GRID_SIZE))
        
        # 绘制网格线（使用半透明效果）
        grid_surface = pygame.Surface((GRID_WIDTH * GRID_SIZE, GRID_HEIGHT * GRID_SIZE), pygame.SRCALPHA)
        for x in range(GRID_WIDTH):
            for y in range(GRID_HEIGHT):
                rect = pygame.Rect(x * GRID_SIZE, y * GRID_SIZE, GRID_SIZE, GRID_SIZE)
                pygame.draw.rect(grid_surface, (50, 50, 100, 80), rect, 1)  # 半透明网格线
        self.screen.blit(grid_surface, (self.game_area_x, game_area_y))
        
        # 绘制已落下的方块
        for y in range(GRID_HEIGHT):
            for x in range(GRID_WIDTH):
                color = board[y][x]
                if color != 0:
                    self.draw_cell_with_effects(x, y, color, False)
    
    def draw_cell_with_effects(self, x, y, color, is_ghost=False):
        """绘制带有光影效果的单元格"""
        rect_x = self.game_area_x + x * GRID_SIZE
        rect_y = 30 + y * GRID_SIZE  # 与游戏区域Y坐标保持一致
        cell_rect = pygame.Rect(rect_x, rect_y, GRID_SIZE - 1, GRID_SIZE - 1)
        
        if is_ghost:
            # 幽灵方块（半透明）
            ghost_color = (color[0], color[1], color[2], 80)
            ghost_surface = pygame.Surface((GRID_SIZE - 1, GRID_SIZE - 1), pygame.SRCALPHA)
            ghost_surface.fill(ghost_color)
            self.screen.blit(ghost_surface, cell_rect)
        else:
            # 主体颜色
            pygame.draw.rect(self.screen, color, cell_rect)
            
            # 添加高光（左上边缘）
            highlight_color = (min(color[0] + 80, 255), min(color[1] + 80, 255), min(color[2] + 80, 255))
            pygame.draw.line(self.screen, highlight_color, (rect_x, rect_y), (rect_x + GRID_SIZE - 2, rect_y), 2)
            pygame.draw.line(self.screen, highlight_color, (rect_x, rect_y), (rect_x, rect_y + GRID_SIZE - 2), 2)
            
            # 添加阴影（右下边缘）
            shadow_color = (max(color[0] - 80, 0), max(color[1] - 80, 0), max(color[2] - 80, 0))
            pygame.draw.line(self.screen, shadow_color, (rect_x + GRID_SIZE - 2, rect_y), 
                            (rect_x + GRID_SIZE - 2, rect_y + GRID_SIZE - 2), 2)
            pygame.draw.line(self.screen, shadow_color, (rect_x, rect_y + GRID_SIZE - 2), 
                            (rect_x + GRID_SIZE - 2, rect_y + GRID_SIZE - 2), 2)
    
    def draw_piece(self, piece, game_over=False):
        """绘制当前方块，带光影效果"""
        if game_over:
            return
        
        shape = piece["shape"]
        color = piece["color"]
        piece_x = piece["x"]
        piece_y = piece["y"]
        
        # 先绘制幽灵方块（显示方块会落到哪里）
        self.draw_ghost_piece(piece)
        
        # 再绘制实际方块
        for i in range(len(shape)):
            for j in range(len(shape[i])):
                if shape[i][j] == 1:
                    x = piece_x + j
                    y = piece_y + i
                    if y >= 0 and y < GRID_HEIGHT and x >= 0 and x < GRID_WIDTH:  # 只绘制在游戏区域内的部分
                        self.draw_cell_with_effects(x, y, color)
    
    def draw_ghost_piece(self, piece):
        """绘制幽灵方块，显示方块会落到哪里"""
        # 计算幽灵方块的最终位置
        ghost_y = piece["y"]
        while True:
            # 检查是否可以继续下落
            collision = False
            for i in range(len(piece["shape"])):
                for j in range(len(piece["shape"][i])):
                    if piece["shape"][i][j] == 1:
                        test_x = piece["x"] + j
                        test_y = ghost_y + i + 1
                        # 检查边界或碰撞
                        if test_y >= GRID_HEIGHT or (test_y >= 0 and test_x >= 0 and test_x < GRID_WIDTH and \
                                                   piece["board"][test_y][test_x] != 0):
                            collision = True
                            break
                if collision:
                    break
            
            if collision:
                break
            ghost_y += 1
        
        # 绘制幽灵方块（如果位置与当前方块不同）
        if ghost_y != piece["y"]:
            for i in range(len(piece["shape"])):
                for j in range(len(piece["shape"][i])):
                    if piece["shape"][i][j] == 1:
                        x = piece["x"] + j
                        y = ghost_y + i
                        if y >= 0 and y < GRID_HEIGHT and x >= 0 and x < GRID_WIDTH:
                            self.draw_cell_with_effects(x, y, piece["color"], True)
    
    def draw_next_piece(self, next_piece):
        """绘制下一个方块预览"""
        # 绘制下一个方块区域边框
        pygame.draw.rect(self.screen, WHITE, (self.next_area_x - 2, 50 - 2, 150 + 4, 150 + 4), 2)
        
        # 绘制标题
        next_text = self.font.render("下一个", True, WHITE)
        self.screen.blit(next_text, (self.next_area_x + 30, 10))
        
        # 绘制方块
        next_shape = next_piece["shape"]
        next_color = next_piece["color"]
        next_shape_height = len(next_shape)
        next_shape_width = len(next_shape[0])
        
        # 居中显示下一个方块
        start_x = self.next_area_x + 75 - (next_shape_width * GRID_SIZE) // 2
        start_y = 50 + 75 - (next_shape_height * GRID_SIZE) // 2
        
        for i in range(next_shape_height):
            for j in range(next_shape_width):
                if next_shape[i][j] == 1:
                    pygame.draw.rect(self.screen, next_color, 
                                    (start_x + j * GRID_SIZE, start_y + i * GRID_SIZE, GRID_SIZE - 1, GRID_SIZE - 1))
    
    def draw_game_info(self, score, level, lines):
        """绘制游戏信息（分数、等级、行数）"""
        score_text = self.font.render("分数: {0}".format(score), True, WHITE)
        level_text = self.font.render("等级: {0}".format(level), True, WHITE)
        lines_text = self.font.render("行数: {0}".format(lines), True, WHITE)
        
        self.screen.blit(score_text, (self.next_area_x + 10, 220))
        self.screen.blit(level_text, (self.next_area_x + 10, 270))
        self.screen.blit(lines_text, (self.next_area_x + 10, 320))
    
    def draw_controls(self):
        """绘制控制说明"""
        # 绘制控制说明标题
        title_surface = self.small_font.render("操作说明:", True, (255, 255, 255))
        self.screen.blit(title_surface, (SCREEN_WIDTH - 250, SCREEN_HEIGHT - 200))
        
        controls_texts = [
            "← →: 移动方块",
            "↑: 旋转方块",
            "↓: 软降",
            "空格: 硬降",
            "P: 暂停/继续",
            "R: 重新开始"
        ]
        
        y_offset = SCREEN_HEIGHT - 160
        for text in controls_texts:
            text_surface = self.small_font.render(text, True, (200, 200, 200))
            self.screen.blit(text_surface, (SCREEN_WIDTH - 250, y_offset))
            y_offset += 25
    
    def draw_info(self, score, level, lines):
        """绘制游戏信息（分数、等级、消除行数）"""
        # 绘制信息面板背景
        info_panel = pygame.Rect(SCREEN_WIDTH - 250, 100, 200, 200)
        pygame.draw.rect(self.screen, (30, 30, 60), info_panel)
        pygame.draw.rect(self.screen, (50, 50, 100), info_panel, 2)
        
        # 绘制分数
        score_text = self.small_font.render("分数:", True, (255, 255, 255))
        score_value = self.small_font.render(str(score), True, (255, 215, 0))
        self.screen.blit(score_text, (SCREEN_WIDTH - 230, 120))
        self.screen.blit(score_value, (SCREEN_WIDTH - 230, 145))
        
        # 绘制等级
        level_text = self.small_font.render("等级:", True, (255, 255, 255))
        level_value = self.small_font.render(str(level), True, (255, 99, 71))
        self.screen.blit(level_text, (SCREEN_WIDTH - 230, 180))
        self.screen.blit(level_value, (SCREEN_WIDTH - 230, 205))
        
        # 绘制消除行数
        lines_text = self.small_font.render("消除行数:", True, (255, 255, 255))
        lines_value = self.small_font.render(str(lines), True, (64, 224, 208))
        self.screen.blit(lines_text, (SCREEN_WIDTH - 230, 240))
        self.screen.blit(lines_value, (SCREEN_WIDTH - 230, 265))
    
    def draw_pause_screen(self):
        """绘制暂停界面"""
        # 创建半透明覆盖层
        overlay = pygame.Surface((SCREEN_WIDTH, SCREEN_HEIGHT), pygame.SRCALPHA)
        overlay.fill((0, 0, 0, 128))
        self.screen.blit(overlay, (0, 0))
        
        # 绘制暂停文字
        pause_text = self.large_font.render("游戏暂停", True, (255, 255, 255))
        pause_rect = pause_text.get_rect(center=(SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2))
        self.screen.blit(pause_text, pause_rect)
        
        # 绘制继续提示
        continue_text = self.small_font.render("按 P 键继续", True, (200, 200, 200))
        continue_rect = continue_text.get_rect(center=(SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2 + 50))
        self.screen.blit(continue_text, continue_rect)
    
    def draw_game_over_screen(self, score):
        """绘制游戏结束界面"""
        # 创建半透明覆盖层
        overlay = pygame.Surface((SCREEN_WIDTH, SCREEN_HEIGHT), pygame.SRCALPHA)
        overlay.fill((0, 0, 0, 192))
        self.screen.blit(overlay, (0, 0))
        
        # 绘制游戏结束文字
        game_over_text = self.large_font.render("游戏结束", True, (255, 0, 0))
        game_over_rect = game_over_text.get_rect(center=(SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2 - 50))
        self.screen.blit(game_over_text, game_over_rect)
        
        # 绘制分数
        score_text = self.small_font.render("最终分数:", True, (255, 255, 255))
        score_value = self.small_font.render(str(score), True, (255, 215, 0))
        score_rect = score_text.get_rect(center=(SCREEN_WIDTH // 2 - 40, SCREEN_HEIGHT // 2))
        score_val_rect = score_value.get_rect(center=(SCREEN_WIDTH // 2 + 70, SCREEN_HEIGHT // 2))
        self.screen.blit(score_text, score_rect)
        self.screen.blit(score_value, score_val_rect)
        
        # 绘制重新开始提示
        restart_text = self.small_font.render("按 R 键重新开始", True, (200, 200, 200))
        restart_rect = restart_text.get_rect(center=(SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2 + 50))
        self.screen.blit(restart_text, restart_rect)
    
    def draw_game_area(self):
        """绘制游戏区域边框"""
        pygame.draw.rect(self.screen, WHITE, 
                        (self.game_area_x - 2, 50 - 2, GRID_WIDTH * GRID_SIZE + 4, GRID_HEIGHT * GRID_SIZE + 4), 2)
    
    def draw(self, tetris_game):
        """绘制整个游戏画面"""
        # 先清空屏幕为蓝色背景
        self.screen.fill((0, 0, 100))
        
        # 绘制游戏标题
        self.draw_title()
        
        # 使用try-except确保基本功能可用
        try:
            # 绘制简单的游戏区域边框
            pygame.draw.rect(self.screen, (255, 255, 255), (50, 100, 300, 600), 2)
            
            # 如果游戏对象存在必要属性，则绘制游戏元素
            if hasattr(tetris_game, 'board'):
                # 绘制游戏板
                self.draw_board(tetris_game.board)
                
                # 绘制当前方块
                if hasattr(tetris_game, 'current_piece') and tetris_game.current_piece:
                    self.draw_piece(tetris_game.current_piece)
                
                # 绘制游戏信息
                score = getattr(tetris_game, 'score', 0)
                level = getattr(tetris_game, 'level', 1)
                lines = getattr(tetris_game, 'lines', 0)
                self.draw_game_info(score, level, lines)
            
            # 绘制控制说明
            self.draw_controls()
            
            # 处理游戏状态显示
            if hasattr(tetris_game, 'paused') and tetris_game.paused:
                self.draw_pause_screen()
            elif hasattr(tetris_game, 'game_over') and tetris_game.game_over:
                score = getattr(tetris_game, 'score', 0)
                self.draw_game_over_screen(score)
                
        except Exception as e:
            # 如果发生错误，至少确保基本显示
            error_text = self.small_font.render("渲染错误: " + str(e), True, (255, 0, 0))
            self.screen.blit(error_text, (50, 500))
    
    def add_particles(self, x, y, color, count=10):
        """添加爆炸粒子效果"""
        for _ in range(count):
            # 粒子大小、速度和方向随机
            size = random.randint(2, 4)
            speed_x = random.uniform(-2, 2)
            speed_y = random.uniform(-2, 2)
            # 添加粒子
            self.particles.append({
                "x": x,
                "y": y,
                "size": size,
                "speed_x": speed_x,
                "speed_y": speed_y,
                "color": color,
                "life": 255  # 粒子生命值（透明度）
            })
    
    def update_and_draw_particles(self):
        """更新和绘制粒子效果"""
        for particle in self.particles[:]:
            # 更新粒子位置
            particle["x"] += particle["speed_x"]
            particle["y"] += particle["speed_y"]
            # 减少生命值
            particle["life"] -= 5
            
            # 绘制粒子
            if particle["life"] > 0:
                # 创建半透明的粒子表面
                particle_surface = pygame.Surface((particle["size"] * 2, particle["size"] * 2), pygame.SRCALPHA)
                alpha = particle["life"]
                color_with_alpha = (particle["color"][0], particle["color"][1], particle["color"][2], alpha)
                pygame.draw.circle(particle_surface, color_with_alpha, 
                                  (particle["size"], particle["size"]), particle["size"])
                self.screen.blit(particle_surface, 
                                (particle["x"] - particle["size"], particle["y"] - particle["size"]))
            else:
                # 移除已消失的粒子
                self.particles.remove(particle)